home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libcan / candisp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  7.7 KB  |  345 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    candisp -
  19.  *        Display parts of a canvas onto the screen.
  20.  *
  21.  *                Paul Haeberli - 1991
  22.  *
  23.  *    exports
  24.  *
  25.     int paintpos(xpos,ypos,pos,strokeno,minm,maxm)
  26.     void displaysetup(drct,scan,sx,sy)
  27.     void displaycanvas(c)
  28.     void setrgbmode(rgb)
  29.     void setcurzoom(z)
  30.     int getcurzoom()
  31.     float getzoomfactor();
  32.     void drawborder(c);
  33.     canvas *screentoscanvas(x1,y1,x2,y2)
  34.  *
  35.  */
  36. #include "gl.h"
  37. #include "canvas.h"
  38. #include "vect.h"
  39. #include "rct.h"
  40. #include "math.h"
  41.  
  42. #define DRAWBUFSIZE    (200*200)
  43.  
  44. static unsigned long *drawbuf;
  45. static float curzfactor; 
  46. static int curzoom, visible;
  47. static int visdxorg, visdyorg;     /* origin of the vis part in dest coords */
  48. static int viszxorg, viszyorg;  /* origin of the vis part in zoomed coords */
  49. static rct visrct;        /* the visible part of the canvas */
  50. static rct disprct;        /* the displayed rect in screen coords */
  51. static rct fulldisprct;        /* the full rect in screen coords */
  52. static rct scrrct;        /* the screen rect in screen coords */
  53. static float lastx, lasty;
  54. static int usergb;
  55.  
  56. static displaysmallcanvas();
  57. static mylrectwrite();
  58.  
  59. int paintpos(xpos,ypos,pos,strokeno,minm,maxm)
  60. int xpos, ypos;
  61. vect *pos;
  62. float minm,maxm;
  63. {
  64.     float dx, dy, mag, sc;
  65.     int retval;
  66.  
  67.     pos->x = (xpos-visdxorg-scrrct.xmin)/curzfactor;
  68.     pos->y = (ypos-visdyorg-scrrct.ymin)/curzfactor;
  69.     if(strokeno != 0) {
  70.     dx = pos->x-lastx;
  71.     dy = pos->y-lasty;
  72.     mag = fsqrt(dx*dx+dy*dy);
  73.     if(mag>maxm) {
  74.         sc = maxm/mag;
  75.         pos->x = lastx+sc*dx;
  76.         pos->y = lasty+sc*dy;
  77.         lastx = pos->x;
  78.         lasty = pos->y;
  79.         return 1;
  80.     } else if(mag<minm) {
  81.         lastx = pos->x;
  82.         lasty = pos->y;
  83.         return 0;
  84.      }
  85.     }
  86.     lastx = pos->x;
  87.     lasty = pos->y;
  88.     return 1;
  89. }
  90.  
  91. void displaysetup(drct,scan,sx,sy)
  92. rct *drct;
  93. canvas *scan;
  94. int sx, sy;
  95. {
  96.     int centx, centy;    /* center of the display */
  97.  
  98.     scrrct = *drct;
  99.     visible = 0;
  100.     rctcenter(drct,¢x,¢y);
  101.     viszxorg = round(centx/curzfactor-sx);
  102.     visdxorg = curzfactor*viszxorg;
  103.     viszyorg = round(centy/curzfactor-sy);
  104.     visdyorg = curzfactor*viszyorg;
  105.     disprct.xmin = 0;
  106.     disprct.xmax = (drct->xmax-drct->xmin)/curzfactor;
  107.     disprct.ymin = 0;
  108.     disprct.ymax = (drct->ymax-drct->ymin)/curzfactor;
  109.     rctoffset(&disprct,-viszxorg,-viszyorg);
  110.     visible = rctinter(&disprct,&scan->area,&visrct);
  111.     fulldisprct = scan->area;
  112.     disprct = visrct;
  113.  
  114.     rctoffset(&disprct,viszxorg,viszyorg);
  115.     disprct.xmax++;
  116.     disprct.ymax++;
  117.     rctscale(&disprct,curzfactor);
  118.     rctoffset(&disprct,drct->xmin,drct->ymin);
  119.     disprct.xmax--;
  120.     disprct.ymax--;
  121.     rctshrink(&disprct,-1,-1);
  122.  
  123.     rctoffset(&fulldisprct,viszxorg,viszyorg);
  124.     fulldisprct.xmax++;
  125.     fulldisprct.ymax++;
  126.     rctscale(&fulldisprct,curzfactor);
  127.     rctoffset(&fulldisprct,drct->xmin,drct->ymin);
  128.     fulldisprct.xmax--;
  129.     fulldisprct.ymax--;
  130.     rctshrink(&fulldisprct,-1,-1);
  131. }
  132.  
  133. void displaycanvas(c)
  134. canvas *c;
  135. {
  136.     int y, nx, ny, y1, used;
  137.     unsigned long *dptr, *sptr;
  138.  
  139.     if(!visible)
  140.     return;
  141.     if(!rctinter(&visrct,&c->dirt,&c->dirt))
  142.     return;
  143.     if(curzfactor<1.0) {
  144.     displaysmallcanvas(c,visdxorg,visdyorg);
  145.     return;
  146.     }
  147.     if(c->dirt.xmin == 0 && c->dirt.xmax == c->xsize-1) {
  148.     dptr = c->data+c->dirt.ymin*c->xsize;
  149.     mylrectwrite(viszxorg,       viszyorg+c->dirt.ymin,
  150.              viszxorg+c->xsize-1,viszyorg+c->dirt.ymax,dptr);
  151.     } else {
  152.     nx = c->dirt.xmax-c->dirt.xmin+1;
  153.     ny = c->dirt.ymax-c->dirt.ymin+1;
  154.     if(!drawbuf) 
  155.         drawbuf = (unsigned long *)mymalloc(DRAWBUFSIZE*sizeof(long));
  156.     y1 = c->dirt.ymin;
  157.     while(1) {
  158.         dptr = drawbuf;
  159.         used = 0;
  160.         for(y=y1; y<=c->dirt.ymax; y++) {
  161.         sptr = &c->data[c->dirt.xmin+y*c->xsize];
  162.         bcopy(sptr,dptr,nx*sizeof(long));
  163.         dptr += nx;
  164.         used += nx;
  165.         if((used+nx)>DRAWBUFSIZE)
  166.             break;
  167.         }
  168.         mylrectwrite(viszxorg+c->dirt.xmin,viszyorg+y1,
  169.              viszxorg+c->dirt.xmax,viszyorg+y-1,drawbuf);
  170.         if(y > c->dirt.ymax)
  171.         break;
  172.         y1 = y;
  173.     }
  174.     }
  175. }
  176.  
  177. static displaysmallcanvas(c,dx,dy)
  178. canvas *c;
  179. int dx, dy;
  180. {
  181.     int redfactor;
  182.     int x, y, nx, ny, used;
  183.     int x1, x2, y1, y2;
  184.     unsigned long *dptr, *sptr;
  185.  
  186.     redfactor = round(1.0/curzfactor);
  187.     x1 = c->dirt.xmin/redfactor;
  188.     x2 = c->dirt.xmax/redfactor;
  189.     y1 = c->dirt.ymin/redfactor;
  190.     y2 = c->dirt.ymax/redfactor;
  191.     nx = x2 - x1 + 1;
  192.     ny = y2 - y1 + 1;
  193.     if(!drawbuf) 
  194.     drawbuf = (unsigned long *)mymalloc(DRAWBUFSIZE*sizeof(long));
  195.     while(1) {
  196.     dptr = drawbuf;
  197.     used = 0;
  198.     for(y=y1; y<=y2; y++) {
  199.         sptr = &c->data[y*redfactor*c->xsize+x1*redfactor];
  200.         x = nx;
  201.         while(x--) {
  202.         *dptr++ = *sptr;
  203.         sptr += redfactor;
  204.         }
  205.         used += nx;
  206.         if((used+nx)>DRAWBUFSIZE)
  207.         break;
  208.     }
  209.     mylrectwrite(dx+x1,dy+y1,dx+x2,dy+y-1,drawbuf);
  210.     if(y > y2)
  211.         break;
  212.     y1 = y;
  213.     }
  214. }
  215.  
  216. static mylrectwrite(x1,y1,x2,y2,buf)
  217. int x1, y1, x2, y2;
  218. unsigned long *buf;
  219. {
  220.     int nx, ny;
  221.  
  222.     nx = x2-x1;
  223.     ny = y2-y1;
  224.     if(curzfactor>=1.0) {
  225.     x1 = curzfactor*x1;
  226.     y1 = curzfactor*y1;
  227.     }
  228.     x1 += scrrct.xmin;
  229.     y1 += scrrct.ymin;
  230.     x2 = x1+nx;
  231.     y2 = y1+ny;
  232.     if(usergb)
  233.     lrectwrite(x1,y1,x2,y2,buf);
  234.     else
  235.     ditlrectwrite(x1,y1,x2,y2,buf);
  236. }
  237.  
  238. void setrgbmode(rgb)
  239. int rgb;
  240. {
  241.     if(rgb) {
  242.     RGBmode();
  243.     gconfig();
  244.     usergb = 1;
  245.     } else {
  246.     cmode();
  247.     gconfig();
  248.     usergb = 0;
  249.     }
  250.     colorinit();
  251. }
  252.  
  253. void setcurzoom(z)
  254. int z;
  255. {
  256.     curzoom = z;
  257.     if(z>=1)
  258.     curzfactor = z;
  259.     else 
  260.     curzfactor = 1.0/(2.0-z);
  261.     if(usergb) {
  262.     if(curzfactor<1.0)
  263.         rectzoom(1.0,1.0);
  264.     else
  265.         rectzoom(curzfactor,curzfactor);
  266.     } else {
  267.     rectzoom(1.0,1.0);
  268.     if(curzfactor<1.0)
  269.         ditrectzoom(1.0,1.0);
  270.     else
  271.         ditrectzoom(curzfactor,curzfactor);
  272.     }
  273. }
  274.  
  275. int getcurzoom()
  276. {
  277.     return curzoom;
  278. }
  279.  
  280. float getzoomfactor()
  281. {
  282.     return curzfactor;
  283. }
  284.  
  285. #define DELTA     (10.0*curzfactor)
  286.  
  287. void drawborder(c)
  288. canvas *c;
  289. {
  290.     if(!visible) {
  291.     rctfill(&scrrct);
  292.     } else {
  293.     rgbi(64,64,64);
  294. /* fill bottom */
  295.     if(scrrct.ymin<disprct.ymin) 
  296.         fillrect(scrrct.xmin-0.5,scrrct.ymin-0.5,
  297.              scrrct.xmax+1.5,disprct.ymin-0.5);
  298. /* fill left */
  299.     if(scrrct.xmin<disprct.xmin) 
  300.         fillrect(scrrct.xmin-0.5,scrrct.ymin-0.5,
  301.              disprct.xmin-0.5,scrrct.ymax+1.5);
  302. /* fill right */
  303.     if(scrrct.xmax>disprct.xmax) 
  304.         fillrect(disprct.xmax+0.5,scrrct.ymin-0.5,
  305.              scrrct.xmax+0.5,scrrct.ymax+1.5);
  306. /* fill top */
  307.     if(scrrct.ymax>disprct.ymax) 
  308.         fillrect(scrrct.xmin-0.5,disprct.ymax+0.5,
  309.              scrrct.xmax+1.5,scrrct.ymax+1.5);
  310. /* draw the shadow */
  311.     rgbi(32,32,32);
  312.     fillrect(fulldisprct.xmax+0.5,fulldisprct.ymin-DELTA,
  313.          fulldisprct.xmax+0.5+DELTA,fulldisprct.ymax-DELTA);
  314.     fillrect(fulldisprct.xmin+0.5+DELTA,fulldisprct.ymin-DELTA,
  315.          fulldisprct.xmax+0.5+DELTA,fulldisprct.ymin-0.5);
  316.  
  317. /* draw the rectangle */
  318.     rgbi(0,0,0);
  319.     rctdraw(&disprct);
  320.     }
  321. }
  322.  
  323. canvas *screentocanvas(x1,y1,x2,y2)
  324. int x1, y1, x2, y2;
  325. {
  326.     int temp, xsize, ysize;
  327.     canvas *can;
  328.  
  329.     if(x1>x2) {
  330.         temp = x1;
  331.         x1 = x2;
  332.         x2 = temp;
  333.     }
  334.     if(y1>y2) {
  335.         temp = y1;
  336.         y1 = y2;
  337.         y2 = temp;
  338.     }
  339.     xsize = x2-x1+1;
  340.     ysize = y2-y1+1;
  341.     can = newcanvas(xsize,ysize);
  342.     readdisplay(x1,y1,x2,y2,can->data,0);
  343.     return can;
  344. }
  345.